home *** CD-ROM | disk | FTP | other *** search
- /*
- post / 郵便番号検索プログラム
-
- p_uni.c / 汎用関数部
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <sys/dos.h>
- #include <mbstring.h>
- #include "post.h"
-
- static short _FEP_OFF[]={0x4878,0x0000,0x4878,0x0001,0xff22,0x504f,0x4e75};
- int (*fep_off)()=(void*)_FEP_OFF;
-
-
- /*
- 全角チェック
-
- 渡されたポインタの位置の2バイトを1文字と見なして検査
- 全角なら1を返し、そうでなければ0を返す
- */
- int
- iskan( uchar *kan )
- {
- int checkwork; /* 漢字検査用ワーク */
-
- checkwork = ((int)*kan * 256) + (int)*(++kan);
-
- return (ismbclegal( checkwork )) ? 1 : 0;
- }
-
-
- /*
- デリミタかどうか判定
-
- デリミタ文字でなければ1を
- デリミタ文字なら0を返す
- */
- int
- is_not_delim( char delim_wk )
- {
- if( delim_wk >= 0x20 && delim_wk <= 0x27 ) {
- return 0;
- } else if( delim_wk >= 0x2a && delim_wk <= 0x2b ) {
- return 0;
- } else if( delim_wk >= 0x3a && delim_wk <= 0x3b ) {
- return 0;
- } else {
- return 1;
- }
- }
-
-
- /*
- 先頭2字検査
-
- 渡された文字列と input_str の、先頭の全角2文字を比較する
- */
- int
- sentou_niji( uchar *chk_str )
- {
- int i1 = 0,
- i2 = 0, /* ループ用 */
- len_str = 0; /* 文字列長さ */
-
- len_str = strlen( input_str );
-
- i2 = (len_str == 2) ? 1 : 3; /* 全角何文字分か */
-
- for( i1=0; i1<=i2; i1++ ) {
- if( (uchar)chk_str[i1] != (uchar)input_str[i1] ) {
- return 0;
- }
- }
-
- return 1;
- }
-
-
- /*
- 次のデリミタ文字まで aiを読み飛ばし
- */
- void
- pass_next_han()
- {
- uchar rea_wk;
-
- ofs++; /* 1文字読み飛ばし */
-
- while( 1 ) {
- rea_wk = buf[ ofs++ ];
-
- if( !is_not_delim( rea_wk ) ) { /* デリミタである */
- break;
- } else {
- continue;
- }
- }
-
- --ofs; /* 1文字戻す */
-
- return;
- }
-
-
- /*
- 次のデリミタ文字まで aiを読み飛ばし(その2)
- */
- void
- pass_next_han2( uchar wk )
- {
- uchar rea_wk;
-
- ofs++; /* 1文字読み飛ばし */
-
- while( 1 ) {
- rea_wk = buf[ ofs++ ];
-
- if( !is_not_delim( rea_wk ) ) { /* デリミタである */
- if( rea_wk == wk ) { /* デリミタが一致 */
- break;
- }
- } else {
- continue;
- }
- }
-
- --ofs; /* 1文字戻す */
-
- return;
- }
-
-
- /*
- ofs位置のデリミタをチェックする
-
- 引数: 0ならデリミタかどうか
- 1なら $ (市内区)かどうか
-
- いずれも、そうであれば1を返す
- */
- int
- check_next_delim( int stype )
- {
- int ret_val = 0;
- uchar read_work;
-
- read_work = buf[ ofs ];
-
- if( stype == 1 ) { /* 市内区チェックである */
-
- ret_val = ( read_work == '$' ) ? 1 : 0;
-
- } else { /* デリミタチェックである */
-
- ret_val = ( !is_not_delim( read_work ) ) ? 1 : 0;
- }
-
- return ret_val;
- }
-
-
- /*
- 得たポインタに、デリミタに合わせて「市区町村」の文字を付加する
-
- 引数: *str_p 文字列を付加するポインタ
- delim_code デリミタコード
- */
- void
- fuka_delim( uchar *str_p, int delim_code )
- {
- if( delim_code == 5 ) {
- delim_code = 1; /* 市内区のコードが来たら、区のコードと読み替える */
- }
-
- strcat( str_p, kanji_shiku[ delim_code ] );
-
- return;
- }
-
-
- /*
- 受け取ったポインタに、デリミタ kou までの文字をセットする
-
- 1994.03.04 : 構造バグのため全改訂
- */
- void
- koumoku_set( uchar *cwork, uchar kou )
- {
- int len_str = 0; /* 文字列長さ用 */
-
- uchar *workptr, *testptr;
-
- len_str = strlen( input_str ); /* input_strの長さを得る */
-
- /* 最終位置を探す */
- testptr = strstr( input_str, kanji_shiku[ kou ] ); /* 最初の位置を探す */
- /* =必ず発見できる。 */
- workptr = testptr; /* 保存する */
-
- while( 1 ) {
- if( (testptr = strstr( workptr+1, kanji_shiku[ kou ] )) == NULL ) {
- break;
- } else {
- workptr = testptr;
- }
- }
-
- workptr++; /* ポインタはデリミタ文字の1バイト目を指しているので、 */
- /* 1バイト足して調整する */
-
- testptr = input_str; /* 注意:ポインタを使い回してる */
-
- while(1) {
- *(cwork++) = *(testptr++); /* コピーする */
-
- if( testptr == workptr+1 ) { /* デリミタまでコピーしたら */
- break; /* 終わる */
- }
- }
- *cwork = '\0'; /* 最終位置に終端記号を付加 */
-
- return;
- }
-
-
- /*
- 次のデリミタ半角文字までを得て、渡されたポインタ位置に付加する。
-
- 引数: *str_p 文字列を付加するポインタ
- */
- void
- get_next_han( uchar *str_p )
- {
- uchar rea_wk; /* 読み出しワーク */
-
- while( 1 ) {
- rea_wk = buf[ ofs++ ];
-
- if( !is_not_delim( rea_wk ) ) { /* デリミタである */
-
- break; /* 終わり */
-
- } else if( isdigit( rea_wk ) ) { /* 住所番号 */
- *(str_p++) = 0x82; /* 全角数字の1バイト目 */
- *(str_p++) = rea_wk + 0x1f; /* 1fを足してSJIS化する */
- continue;
-
- } else { /* たぶん漢字である */
-
- *(str_p++) = rea_wk;
- *(str_p++) = buf[ ofs++ ];
- continue;
- }
- }
-
- *str_p = '\0'; /* 終端文字をセット */
-
- --ofs; /* 1文字戻す */
-
- return;
- }
-
-
- /*
- 次のデリミタ半角文字までを得て、渡されたポインタ位置に付加する(その2)
- 読みがな用
-
- 引数: *str_p 文字列を付加するポインタ
- */
- void
- get_next_han2( uchar *str_p )
- {
- uchar rea_wk; /* 読み出しワーク */
-
- ofs++;
-
- while( 1 ) {
- rea_wk = buf[ ofs++ ];
-
- if( !is_not_delim( rea_wk ) ) { /* デリミタである */
-
- break; /* 終わり */
-
- } else { /* たぶん半角カタカナである */
-
- *(str_p++) = rea_wk;
- continue;
- }
- }
-
- *str_p = '\0'; /* 終端文字をセット */
-
- --ofs; /* 1文字戻す */
-
- return;
- }
-
-
- /*
- 渡されたデリミタ文字を判定してデリミタコードを返す
-
- 市内区は1が返る
- */
- int
- ret_delim_code( uchar delim )
- {
- int i1 = 0; /* ループ汎用 */
-
- for( i1=0; i1<=5; i1++ ) {
- if( delim == delim_shiku[ i1 ] ) {
- return (i1 == 5) ? 1 : i1;
- }
- }
- printf("異常 401 : デリミタ文字に該当なし(ret_delim_code):|%c|\n", delim );
-
- return -1;
- }
-
-
- /*
- 後の全角1文字を削除する
- */
- void
- del_last_char( uchar workstr[] )
- {
- int len_str = 0;
-
- len_str = strlen( workstr );
-
- workstr[ len_str - 2 ] = '\0';
-
- return;
- }
-
-
- /*
- 直前にある、指定されたデリミタまで後戻り
-
- オフセットofsはデリミタの次の位置を指すこととなる
-
- '.' の場合、とにかくデリミタまで逆戻りする
- */
- void
- pass_back_han( uchar delim )
- {
- uchar rea_wk;
-
- --ofs; /* 1文字読み戻し */
-
- while ( ofs >= 0 ) {
- rea_wk = buf[ ofs-- ];
-
- if( !is_not_delim( rea_wk ) ) { /* デリミタだ */
- if( delim == '.' ) { /* デリミタまでという指定なら */
- break; /* 終わる */
- } else if( rea_wk == delim ) { /* 一致だ */
- break; /* 終わりだ */
- }
- }
- }
-
- ofs += 2; /* 補正 */
-
- return;
- }
-
-
- /*
- 渡された「文字列1」中に「文字列2」が何文字入っているかチェックする
-
- 全角専用
- */
- int
- strschks( uchar *moji1, uchar *moji2 )
- {
- int num_of_str = 0, /* 見付かった文字列の数 */
- len_moji = 0, /* 文字列1の長さ */
- i1; /* ループ汎用 */
- uchar wk1, wk2; /* テスト用1バイト目、2バイト目 */
-
- len_moji = strlen( moji1 ); /* 目的の文字列の長さを算出 */
-
- wk1 = moji2[0]; /* 検索目標の文字をセット */
- wk2 = moji2[1];
-
- /*
- 全角を1文字ずつ照合する
- 2バイト文字チェックは行う必要はない(ループは2とびなので)
- 先頭の全角1文字は照合しないので、ループは2から
- */
- for( i1=2; i1<=(len_moji-1); i1+=2 ) {
- if( (moji1[i1] == wk1) && (moji1[i1+1] == wk2) ) {
- num_of_str++;
- }
- }
-
- return( num_of_str );
- }
-
-
- /*
- 文字列input_str の頭についている文字列を削除する関数
-
- 全角専用
-
- uchar *purge_str : 文字列からパージされるところの文字列(県名とか)
- */
- void
- str_purge( uchar *purge_str )
- {
- uchar work_str[256];
- int i1, /* ループ汎用 */
- len_str1 = 0, /* 長さワーク:削除される側の文字列用 */
- len_str2 = 0; /* 長さワーク:削除する文字列purge_str用 */
-
- len_str1 = strlen( input_str ); /* 長さを得る */
- len_str2 = strlen( purge_str );
-
- strcpy( work_str, input_str ); /* ワークにコピー */
-
- for( i1=len_str2; i1<=len_str1-1; ++i1 ) {
- input_str[i1 - len_str2] = work_str[i1];
- }
-
- input_str[ len_str1 - len_str2 ] = '\0';
-
- return;
- }
-
-
- /*
- 入力文字列の半角検査
-
- 入力文字列中に半角が入っている場合、1を返す
- */
- int
- hankaku_test()
- {
- int i1 = 0, /* ループ用 */
- hankaku = 0, /* 半角チェックスイッチ */
- suuji = 0, /* 数字チェックスイッチ */
- len = 0; /* 文字列長さ */
-
- len = strlen( input_str );
-
- hankaku = 0;
- for( i1=0; i1<=len-1; i1+=2 ) {
-
- if( !ismbblead( (int)input_str[i1] ) ||
- !iskan( &input_str[i1] ) ) { /* 半角があったぞ */
- hankaku = 1;
- }
- }
-
- if( hankaku ) {
- suuji = 1;
- for( i1=0; i1<=len-1; i1++ ) {
- if( !isdigit( input_str[i1] ) && /* 数字でもなく、 */
- !ispunct( input_str[i1] ) ) { /* 記号でもないなら、 */
- suuji = 0; /* 数字チェックスイッチをオフる */
- break;
- }
- }
- }
-
- if( suuji ) { /* 数字スイッチがまだ立っていれば */
- return 2; /* 全部数字である */
- } else if( hankaku ) { /* 数字ではないが半角が入っている */
- return 1;
- }
-
- return 0; /* 半角はなかった */
- }
-
-
- /*
- ヵとヶのテスト
-
- ヵかヶを見付けたら、それぞれカとケに変換する
- */
- void
- ke_test()
- {
- int i1 = 0, /* ループ汎用 */
- len = 0; /* 長さ */
-
- len = strlen( input_str );
-
- for( i1=0; i1<=len-1; i1+=2 ) {
-
- if( input_str[ i1 ] == 0x83 ) { /* 83 …… ヵとヶの1バイト目 */
-
- if( input_str[ i1+1 ] == 0x95 ) { /* ヵ */
- input_str[ i1+1 ] = 0x4a; /* カ */
- } else if( input_str[ i1+1 ] == 0x96 ) { /* ヶ */
- input_str[ i1+1 ] = 0x50; /* ケ */
- }
- }
- }
-
- return;
- }
-
-
- /*
- post.datを県名により頭出しする
- */
- void
- ken_atamadashi()
- {
- pref_ofs = bm_find( ' ', pref[num_pref], 0 );
-
- return;
- }
-
-
- /*
- 都道府県を確定する
- */
- void
- todo_kakutei()
- {
- uchar tbuf[64], /* 県/郡確定用ワーク */
- *tbuf_p; /* tbuf用ポインタ */
-
- int i1, /* ループ汎用 */
- ofs_taihi = 0; /* オフセット退避用 */
-
-
- tbuf[ 0 ] = '\0';
- tbuf_p = tbuf;
-
- ofs_taihi = ofs; /* オフセットの待避 */
-
- pass_back_han( ' ' ); /* 県デリミタまで後戻り */
- get_next_han( tbuf_p ); /* 県名を得る */
- get_next_han2( yomi0 ); /* 県名の読みを得る */
-
- for( i1=0; i1<=47-1; i1++ ) {
- if( strcmp( tbuf, pref[i1] ) == 0 ) {
- num_pref = i1;
- todo_sw = 1;
- break;
- }
- }
- ofs = ofs_taihi; /* オフセットの復元 */
-
- return;
- }
-
-
- /*
- 郵便番号整形
-
- nnnnnnn\0 を nnn-nnnn\0 に整形する
- */
- void
- number_seikei( uchar *num_wk )
- {
- num_wk[8] = '\0';
- num_wk[7] = num_wk[6];
- num_wk[6] = num_wk[5];
- num_wk[5] = num_wk[4];
- num_wk[4] = num_wk[3];
- num_wk[3] = '-';
-
- return;
- }
-
-
- /*
- get_next_han の郵便番号専用版
-
- デリミタ * の項目専用
-
- 引数: *str_p 文字列を付加するポインタ
- */
- void
- get_next_num( uchar *str_p )
- {
- uchar rea_wk; /* 読み出しワーク */
-
- while( 1 ) {
- rea_wk = buf[ ofs++ ];
-
- if( !is_not_delim( rea_wk ) ) { /* デリミタである */
-
- break; /* 終わり */
-
- } else { /* たぶん番号である */
-
- *(str_p++) = rea_wk;
- continue;
- }
- }
-
- *str_p = '\0'; /* 終端文字をセット */
-
- --ofs; /* 1文字戻す */
-
- return;
- }
-
-
- /*
- 色付き文字列表示
-
- ヒットした文字列を、色付きで表示する
- 複数ある場合は、最後のヒット文字列を表示
- 両方の文字列とも、文字列長は偶数であることが前提
-
- パラ: uchar *inpstr 表示する文字列
- uchar *irostr 色付きにする文字列
-
- 戻り値:なし
- */
- void
- moji_pr( unsigned char *inpstr, unsigned char *irostr )
- {
- int i1, i2, /* ループ汎用 */
- len_inp=0, /* inpstr の長さ */
- len_inp2 = 0, /* inpstr の長さ(sp削除後) */
- len_iro=0, /* irostr の長さ */
- cofs = 0, /* チェックオフセット */
- cnt = 0, /* カウント */
- hit_sw = 1, /* 照合用スイッチ */
- start_pos=0, /* 色付きスタート位置 */
- end_pos=0; /* 同 終了位置 */
-
- uchar pstr1[256],
- pstr2[256], /* 色付き */
- pstr3[256];
-
- uchar *p1p, *p2p, *p3p, *inp;
-
- /* 長さを得る */
- len_inp = strlen( inpstr );
- len_iro = strlen( irostr );
-
- if( len_inp == 0 || len_iro == 0 ) { /* どちらかがヌルなら */
- return; /* 表示しない */
- }
-
- if( len_inp == len_iro ) { /* 同じ長さなら */
-
- /* 色ありで表示してしまう */
- _dos_c_color( 1 ); /* 水色 */
- fputs( inpstr, stdout );
- _dos_c_color( 3 ); /* 白色 */
-
- return;
- }
-
- /* 場所割り出しの前準備:割り出しの開始地点を求める */
- /* 桁揃えで後ろに半角スペースが付いていることがあるため */
- /* 後ろから検索するので注意 */
- len_inp2 = len_inp;
- for( i1=len_inp-1; i1>=0; i1-- ) {
- if( inpstr[i1] == ' ' ) {
- len_inp2--;
- } else {
- break;
- }
- }
-
- /* 最後に一致する位置を探す( strspn を使ったが、どうもうまくいかん) */
- for( i1=len_inp2 - len_iro; i1>=0; i1-- ) {
- if( inpstr[i1] == irostr[0] ) { /* 先頭が一致した */
- hit_sw = 1;
- /* 0 はチェック済みなので 1 から始める */
- for( i2=1; i2<=len_iro-1; i2++ ) {
- if( inpstr[i1+i2] != irostr[i2] ) { /* もし違ったら */
- hit_sw = 0; /* だめでした */
- break;
- }
- }
- if( !hit_sw ) {
- continue;
- }
- /* ここに来たということは、全一致 */
-
- /* その直前から、2バイトコードの1バイト目になりえない */
- /* コードが出てくる直前まで遡り、バイト数を数える */
- cofs = i1; /* 遡り用 */
- cnt = 0;
- do {
- cofs--;
- if( cofs < 0 ) {
- break;
- }
- /* 1バイト目になる */
- if( ismbblead( inpstr[cofs] ) ) {
- cnt++; /* 数える */
- } else {
- break;
- }
- } while( 1 );
-
- /* 奇数なら、いま合致したところは実は1バイト目ではない */
- if( (cnt % 2) != 0 ) {
- continue;
- }
-
- start_pos = i1; /* 場所を記憶 */
- end_pos = i1 + len_iro;
- break;
- }
- }
-
- /* 切り出す */
- p1p = pstr1;
- p2p = pstr2;
- p3p = pstr3;
-
- inp = &inpstr[0];
-
- if( start_pos != 0 ) { /* 前の色なし文字があれば */
- for( i1=0; i1<=start_pos-1; i1++ ) {
- *p1p++ = *inp++;
- }
- *p1p = '\0';
- /* 最初の色なし文字列を表示 */
- fputs( pstr1, stdout );
- }
-
- for( i1=start_pos; i1<=end_pos-1; i1++ ) {
- *p2p++ = *inp++;
- }
- *p2p = '\0';
- /* 色あり文字列を表示 */
- _dos_c_color( 1 ); /* 水色にする */
- fputs( pstr2, stdout );
- _dos_c_color( 3 ); /* 白に戻す */
-
- if( end_pos != len_inp ) { /* 後ろの色なし文字があれば */
- for( i1=end_pos; i1<=len_inp-1; i1++ ) {
- *p3p++ = *inp++;
- }
- *p3p = '\0';
- /* 最後の色なし文字列を表示 */
- fputs( pstr3, stdout );
- }
-
- return;
- }
-
-
- /*
- バックトレース
-
- デリミタにぶつかるまで前に戻る
-
- 戻り値:ぶつかったデリミタ
- */
- uchar
- backtrace()
- {
- int lpsw = 1;
- uchar ret_char;
-
- do {
- pass_back_han( '.' );
- ofs--;
-
- switch( buf[ofs] ) { /* デリミタは? */
-
- case '%': /* 字名 */
- case '*': /* 新郵便番号 */
- case '\'': /* 旧郵便番号 */
- case '+': /* 読み */
- break;
-
- case ' ': /* 県 */
- puts("異常 404 : backtrace で県を検出しました");
- exit(1);
-
- case '#': /* 郡 */
- puts("異常 405 : backtrace で郡を検出しました");
- exit(1);
-
- case '!': /* 市 */
- case '$': /* 市内区 */
- case '\"': /* 23区 */
- case ':': /* 町 */
- case ';': /* 村 */
- lpsw = 0;
- break;
-
- default:
- printf("異常 406 : 異常なデリミタを");
- printf("検出しました|%c|\n",buf[ofs]);
- exit(1);
- }
- } while( lpsw );
-
- ret_char = buf[ ofs++ ];
-
- return ret_char;
- }
-
-
- /*
- 政令指定都市チェック
-
- 政令指定都市番号を返す
- 0から11のはず(増えなければの話)
- 合致しなければ -1 を返す
- */
- int
- seirei_check( uchar *teststr )
- {
- int i1, /* ループ汎用 */
- toshi = -1; /* 都市番号 */
-
- uchar seirei_toshi[12][2][10] = { /* 政令指定都市リスト */
- "札幌市", "サツポロシ",
- "仙台市", "センダイシ",
- "千葉市", "チバシ",
- "横浜市", "ヨコハマシ",
- "川崎市", "カワサキシ",
- "名古屋市", "ナゴヤシ",
- "京都市", "キヨウトシ",
- "大阪市", "オオサカシ",
- "神戸市", "コウベシ",
- "広島市", "ヒロシマシ",
- "北九州市", "キタキユウシユウシ",
- "福岡市", "フクオカシ"
- };
-
- int seirei_toshisuu = 12;
-
- /* 市名を特定 */
- toshi = -1;
- for( i1=0; i1<=seirei_toshisuu-1; i1++ ) {
- if( strstr( teststr, seirei_toshi[i1][0] ) != NULL ) {
- toshi = i1;
- break;
- }
- }
-
- return toshi;
- }
-
-
- /*
- 一円チェック
-
- 町村内がすべて同一郵便番号の場合、pnum に書き込む
- */
- void
- ichien_check( uchar *pnum, uchar *knum )
- {
- uchar numwork[12]; /* 郵便番号ワーク */
-
- ofs++;
- get_next_num( numwork );
- number_seikei( numwork );
- ofs++;
- get_next_num( knum );
-
- if( buf[ofs] != '%' ) { /* 字名がない */
- strcpy( pnum, "*" );
- strcat( pnum, numwork ); /* 一円である */
- }
-
- return;
- }
-
-
- /*
- input_strの残り位置のポインタを返す
- */
- uchar *
- nokori( uchar *strwk1, uchar *strwk2 )
- {
- int len_str; /* 文字列長さ */
-
- uchar *ret_ptr; /* 戻り値用ポインタ */
-
- len_str = strlen( strwk1 ); /* オフセットを算出 */
- len_str += strlen( strwk2 );
-
- ret_ptr = input_str; /* ポインタをセット */
- ret_ptr += len_str; /* オフセットを足し込む */
-
- return ret_ptr;
- }
-
-
- /*
- 文字列input_strの指定された範囲をstrwk1にコピーする
- */
- void
- str_bcpy( uchar *strwk1, int start_pos, int end_pos )
- {
- int i1; /* ループ汎用 */
- uchar *input; /* ワークポインタ */
-
- input = input_str; /* ポインタセット */
-
- input += start_pos; /* 開始位置までオフセットを移動 */
-
- for( i1=1; i1<=(end_pos-start_pos+1); i1++ ) { /* 最終位置までコピー */
- *strwk1++ = *input++;
- }
-
- *strwk1 = '\0';
-
- return;
- }
-
-
- /*
- 存在チェック
-
- 発見できれば1を できなければ0を返す
- */
- int
- sonzai_check( uchar *str1, uchar *str2, int d_code1, int d_code2 )
- {
- if( find_strs_pref( str1, d_code1 ) == 0 ) {
- return 0;
-
- } else if( d_code2 != -1 ) {
-
- if( find_strs_kou2( str2, d_code2 ) == 0 ) {
-
- return 0;
- }
- }
-
- return 1; /* 脱落しなければ発見できたということ */
- }
-
-
- /*
- BM法による文字列検索
-
- パラ: uchar delim : デリミタ( '.' 時はデリミタなし)
- uchar patt : 検索パターン
- int first_pos : 検索を開始する位置
-
- 戻り値:発見できれば、検索文字列の次の位置を返す
- 発見できなければ-1を返す
-
- 改良:delim がヌルでも良いことにした
- */
- int
- bm_find( uchar delim, uchar *patt, int first_pos )
- {
- int len_str = 0, /* 文字列長さ */
- long_str = 0, /* 配列長さ */
- i1, i2, i3, /* ループ汎用 */
- cofs = 0, /* 遡り用 */
- cnt = 0, /* 合致数 */
- hyou[ 256 ]; /* BM法検索用の表 */
-
- uchar *pattern, /* 探す文字列ポインタ */
- pattbuf[256], /* 実体 */
- tail, /* 最後の文字 */
- readwk; /* 読み込みワーク */
-
- if( delim == '.' ) {
-
- /* デリミタなしで検索 */
- pattbuf[0] = '\0';
- pattern = pattbuf;
- strcpy( pattern, patt );
-
- } else {
-
- /* デリミタありで検索 */
- pattbuf[0] = delim; /* まずデリミタをセット */
- pattbuf[1] = '\0';
- pattern = pattbuf;
- strcat( pattern, patt ); /* 後に連結 */
- }
-
- len_str = strlen( pattern );
-
- if( len_str == 0 ) {
- printf("異常 407 : bm_find : 文字列長が0です\n");
- exit(1);
- }
-
- tail = pattern[ len_str - 1 ]; /* 最後の文字をセット */
-
- if( delim == '.' && len_str == 2 ) { /* デリミタなしで、しかも2文字なら */
-
- for( i1=first_pos; buf[i1] != '\0'; i1++ ) { /* リニアに探す */
-
- if( buf[i1] == pattbuf[0] ) { /* 1バイト目が合致 */
-
- /* 直前から、2バイトコードの1バイト目になりえない */
- /* コードが出てくる直前まで遡り、バイト数を数える */
- cofs = i1; /* 遡り用 */
- cnt = 0;
- do {
- cofs--;
- if( ismbblead( buf[cofs] ) ) { /* 1バイト目になる */
- cnt++; /* 数える */
- } else {
- break;
- }
- } while( 1 );
- /* 奇数なら、いま合致したところは実は1バイト目ではない */
- if( (cnt % 2) != 0 ) {
- continue;
- }
-
- if( buf[i1+1] == pattbuf[1] ) {
-
- /* 見つかった */
- return i1+1;
- }
- }
- }
-
- } else if( len_str == 1 ) { /* 検索文字列が1文字だけなら */
- for( i1=0; buf[i1] != '\0'; i1++ ) {
- if( buf[i1] == tail ) { /* 見付かった */
- return 1;
- }
- }
- } else { /* 長さが2文字以上 */
- for( i1=0; i1<=255; i1++ ) { /* 配列を右側位置で初期化 */
- hyou[ i1 ] = len_str;
- }
- for( i1=0; i1<len_str-1; i1++ ) { /* 右端以外の右から何番目に */
- hyou[ pattern[ i1 ] ] = len_str - 1 - i1; /* 出てくるか */
- }
-
- /* いまi1はlen_str-1 */
-
- if( first_pos != -1 ) {
- i1 += first_pos; /* 初期位置分ずらす */
- }
-
- long_str = file_len; /* 検索される側の長さ */
-
- while( i1 < long_str ) {
- readwk = buf[i1];
- if( readwk == tail ) { /* 右端が一致した */
- i2 = len_str - 1;
- i3 = i1;
-
- while( pattern[ --i2 ] == buf[ --i3 ] ) {
- if( i2 == 0 ) {
- return i1+1; /* 終わりまで照合できた */
- /* ↑ここのi1+1をi3に変えると */
- /* 発見できた文字列の位置を返す */
- }
- }
- }
- i1 += hyou[ readwk ];
- } /* while終端 */
- } /* if(len... 終端 */
-
- return -1;
- }
-
-
- /*
- ステータスプリント
-
- 今のモードを表示する
- */
- void
- status_print()
- {
- if( k_suppress ) {
- printf("旧番号非表示/");
- } else {
- printf("旧番号表示/");
- }
-
- if( azamei_gentei ) {
- printf("字名限定/");
- } else {
- printf("字名非限定/");
- }
-
- if( kugiri_mode ) {
- printf("区切表示/");
- } else {
- printf("区切非表示/");
- }
-
- if( genmitsu_mode ) {
- printf("厳密検索");
- } else {
- printf("非厳密検索");
- }
-
- printf("\n");
-
- return;
- }
-
-
- /*
- 桁揃え
-
- 二つの文字列の長さを比較し、
- 長い方に合わせてスペースを末尾に付ける
- */
- void
- keta( uchar *s1, uchar *s2 )
- {
- int l1=0, l2=0, /* 長さ */
- sa = 0, /* 差 */
- i1 = 0; /* ループ汎用 */
-
- uchar *tsuke; /* 付ける方のポインタ */
-
-
- l1 = strlen( s1 );
- l2 = strlen( s2 );
-
- if( l1 == l2 ) { /* 同じ長さなら */
- return; /* 処理いらない */
- }
-
- if( l1 < l2 ) {
- sa = l2 - l1;
- tsuke = &s1[ l1 ];
- } else {
- sa = l1 - l2;
- tsuke = &s2[ l2 ];
- }
-
- for( i1=1; i1<=sa; i1++ ) {
- *tsuke++ = ' ';
- }
-
- *tsuke = '\0';
-
- return;
- }
-
-
- /*
- 区切り表示
-
- kugiri が 1 なら | を、0 ならスペースを表示
- */
- void
- kugiri()
- {
- if( kugiri_mode ) {
- printf("|");
- } else {
- printf(" ");
- }
-
- return;
- }